// Ninf-G-XX, ver. 0.1
// Copyright 2011 National Institute of Advanced Industrial Science and Technology
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <sys/types.h>
#include <rpc/rpc.h>
#include "DataOutputStream.hpp"
#include "Constants.hpp"
#include "Exception.hpp"

using namespace ninf::lib;

void
DataOutputStream :: writeChar(char c){
  writeInt(c);
}

void 
DataOutputStream :: writeShort(short s){
  writeInt(s);
}

void
DataOutputStream :: writeInt(int i){
  XDR xdr;
  char buf[4];
  xdrmem_create(&xdr, buf, 4, XDR_ENCODE);
  if (! xdr_int(&xdr, &i))
    EXCEPTION("failed to xdr_int");
  EBEGIN { os->write(buf, 0, xdr_getpos(&xdr)); } EEND
  xdr_destroy(&xdr);
}

void
DataOutputStream :: writeLong(long l){
  writeInt((int)l);
}

void
DataOutputStream :: writeFloat(float f){
  XDR xdr;
  char buf[4];
  xdrmem_create(&xdr, buf, 4, XDR_ENCODE);
  if (! xdr_float(&xdr, &f))
    EXCEPTION("failed to xdr_float");
  EBEGIN { os->write(buf, 0, xdr_getpos(&xdr)); } EEND
  xdr_destroy(&xdr);
}

void
DataOutputStream :: writeDouble(double d){
  XDR xdr;
  char buf[8];
  xdrmem_create(&xdr, buf, 8, XDR_ENCODE);
  if (! xdr_double(&xdr, &d))
    EXCEPTION("failed to xdr_double");
  EBEGIN { os->write(buf, 0, xdr_getpos(&xdr)); } EEND
  xdr_destroy(&xdr); 

}

void
DataOutputStream :: writeString(const char * c){
  XDR xdr;
  int len = strlen(c) + 4 + 5 ;
  char * buf = new char[len];

  xdrmem_create(&xdr, buf, len, XDR_ENCODE);
  if (! xdr_string(&xdr, (char **) &c, XDR_MAX_STRING_LEN))
    EXCEPTION("failed to xdr_string");

  EBEGIN { os->write(buf, 0, xdr_getpos(&xdr)); } EEND
  xdr_destroy(&xdr); 

  delete buf;
}



void 
DataOutputStream :: writeCharArray(int n, const char * c){
  for (int i = 0; i < n; i++)
    writeChar(*(c + i));
}

void 
DataOutputStream :: writeShortArray(int n, short * s){
  for (int i = 0; i < n; i++)
    writeShort(*(s + i));
}

void 
DataOutputStream :: writeIntArray(int n, int * i0){
  for (int i = 0; i < n; i++)
    writeInt(*(i0 + i));
}


void 
DataOutputStream :: writeLongArray(int n, long * l){
  for (int i = 0; i < n; i++)
    writeLong(*(l + i));
}

void 
DataOutputStream :: writeFloatArray(int n,  float * f){
  for (int i = 0; i < n; i++)
    writeFloat(*(f + i));
}


void 
DataOutputStream :: writeDoubleArray(int n, double * d){
  for (int i = 0; i < n; i++)
    writeDouble(*(d + i));
}


void 
DataOutputStream :: writeStringArray(int n, const char ** s){
  for (int i = 0; i < n; i++)
    writeString(*(s + i));
}

void 
DataOutputStream :: flush(){
  os->flush();
}

